package com.turing.post.thirdinterface.impl;

import java.io.Reader;
import java.io.StringReader;
import java.math.BigInteger;
import java.nio.charset.Charset;

import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.input.SAXBuilder;

import com.turing.post.thirdinterface.util.ThirdInterfaceRespCode;
import com.turing.post.util.HexDump;
import com.turing.post.util.PCPSApplicationException;
import com.turing.post.util.PCPSUtil;

/**
 * XML报文解析辅助类
 * @author ZXL
 *
 */
public final class SanHuanXmlHelper {
	/**
	 * XML编码GB18030
	 */
	public static final String XML_CHARSET_GB18030 = "GB18030";
	/**
	 * XML编码UTF-8
	 */
	public static final String XML_CHARSET_UTF = "UTF-8";
	/**
	 * 处理成功
	 */
	public static final String XML_SUCCESS = "00";
	
	/**
	 * 处理失败
	 */
	public static final String XML_FAIL = "10";
	
	/**
	 * 数据库错
	 */
	public static final String XML_DATABASEERROR = "97";
	
	/**
	 *请求包格式错
	 */
	public static final String XML_REQUESTPACKAGE = "99";
	
	/**
	 *对帐文件格式错或未找到(对帐交易时)
	 */
	public static final String XML_RECONCILIATIONERROR = "50";
	
	/**
	 * 开卡验证
	 */
	public static final String XML_OPENCARDVALIDATE = "8010";
	
	/**
	 * 开卡注册
	 */
	public static final String XML_OPENCARDREGISTER = "8015";
	
	/**
	 * 黑名单
	 */
	public static final String XML_BLACKORDER = "8020";
	
	/**
	 * 解除黑名单
	 */
	public static final String XML_REMOVEBLACKORDER = "8021";
	
	/**
	 * 卡赎回
	 */
	public static final String XML_CARDREDEMP = "8030";
	
	/**
	 * 换卡
	 */
	public static final String XML_CHANGECARD = "8040";
	
	/**
	 * 消费数据
	 */
	public static final String XML_CONSUMEDATA = "8050";
	
	
	/**
	 * XML主节点
	 */
	public static final String XML_NODE_TRANSREQUEST = "TransRequest";
	
	/**
	 * XML主节点
	 */
	public static final String XML_NODE_TRANSRESPONSE = "TransResponse";
	/**
	 * XML交易码
	 */
	public static final String XML_NODE_TRANCODE = "TranCode";
	/**
	 * XML输入节点
	 */
	public static final String XML_NODE_REQBODY = "ReqBody";
	
	/**
	 * XML输出节点
	 */
	public static final String XML_NODE_RESPBODY = "RespBody";
	
	/**
	 * XML主机受理时间
	 */
	public static final String XML_NODE_TRANTIME = "TranTime";
	
	/**
	 * XML响应码
	 */
	public static final String XML_NODE_RESPCODE = "RespCode";
	/**
	 * XML错误描述
	 */
	public static final String XML_NODE_RESPERRMSG = "RespErrMsg";
	/**
	 * XML车驾号
	 */
	public static final String XML_NODE_VIN = "Vin";
	
	/**
	 * XML车主姓名(个人或单位)
	 */
	public static final String XML_NODE_NAME = "Name";
	/**
	 * XML车牌号
	 */
	public static final String XML_NODE_AUTONUMBER = "AutoNumber";
	/**
	 * XML气瓶编号
	 */
	public static final String XML_NODE_GASCYLINDERNO = "GasCylinderNo";
	/**
	 * XML气瓶数量
	 */
	public static final String XML_NODE_GASCYLINDERNUM = "GasCylinderNum";
	/**
	 * XML注册编号
	 */
	public static final String XML_NODE_REGNO = "RegNo";
	/**
	 * XML车辆种类
	 */
	public static final String XML_NODE_AUTOTYPE = "AutoType";
	/**
	 * XML到检日期
	 */
	public static final String XML_NODE_EXPIREDDATE = "ExpiredDate";
	
	/**
	 * XML卡号
	 */
	public static final String XML_NODE_CARDNO = "CardNo";
	
	/**
	 * XML原卡号
	 */
	public static final String XML_NODE_OLDCARDNO = "OldCardNo";
	
	/**
	 * 根据字节数组,返回org.jdom2.Document
	 * 
	 * @param ibuf
	 * @return
	 * @throws Exception
	 */
	public static Document getXmlDocumentFromBuffer(byte[] ibuf)
			throws PCPSApplicationException {
		try {
			PCPSUtil.Log(HexDump.EOL + "PCPS request data LEN " + ibuf.length
					+ HexDump.EOL + HexDump.dump(ibuf, 0, 0));
			SAXBuilder builder = new SAXBuilder();
			String reqXml = new String(ibuf, Charset.forName(XML_CHARSET_GB18030))
					.trim();
			Reader in = new StringReader(reqXml);
			return builder.build(in);
		} catch (Exception ex) {
			PCPSUtil.Log("getXmlDocumentFromBuffer error!", ex);
			throw new PCPSApplicationException(ThirdInterfaceRespCode.RC_PARAMETER, 
					"getXmlDocumentFromBuffer error!");
		}
	}

	/**
	 * 增加字符串
	 * 
	 * @param parent
	 * @param nodeName
	 * @param nodeValue
	 */
	public static void addStringElement(Element parent, String nodeName,
			String nodeValue) {
		if (PCPSUtil.isEmpty(nodeValue))
			return;
		Element el = new Element(nodeName);
		el.addContent(nodeValue);
		parent.addContent(el);
	}

	/**
	 * 返回必须存在的字符串
	 * 
	 * @param root
	 * @param nodeName
	 * @return
	 * @throws Exception
	 */
	public static String getMandatoryString(Element root, String nodeName)
			throws PCPSApplicationException {
		Element node = root.getChild(nodeName);
		if (node == null)
			throw new PCPSApplicationException(ThirdInterfaceRespCode.RC_PARAMETER, 
					nodeName + " 不存在!");
		String nodeval = node.getTextTrim();
		if (PCPSUtil.isEmpty(nodeval))
			throw new PCPSApplicationException(ThirdInterfaceRespCode.RC_PARAMETER, 
					nodeName + " 为NULL!");
		return nodeval;
	}

	/**
	 * 获取可选字符串
	 * 
	 * @param root
	 * @param nodeName
	 * @return
	 */
	public static String getOptionalString(Element root, String nodeName) {
		Element node = root.getChild(nodeName);
		return (node != null) ? node.getTextTrim() : "";
	}

	/**
	 * 解析数字
	 * 
	 * @param root
	 * @param nodeName
	 * @return
	 * @throws Exception
	 */
	public static BigInteger getInteger(Element root, String nodeName)
			throws PCPSApplicationException {
		String str = getMandatoryString(root, nodeName);
		BigInteger ival = BigInteger.ZERO;

		try {
			ival = new BigInteger(str);
		} catch (Exception e) {
			throw new PCPSApplicationException(ThirdInterfaceRespCode.RC_PARAMETER, 
					nodeName + " 数字非法!");
		}

		return ival;
	}
}
